const express = require('express')
const path = require('path')
const multiparty = require('multiparty')
const fse = require('fs-extra')
const cors = require('cors')
const bodyParser = require('body-parser')

const app = express()
app.use(bodyParser.json())
app.use(cors())

//提取文件后缀名
const extractExt = filename => {
    return filename.slice(filename.lastIndexOf('.'), filename.length)
}

const UPLOAD_DIR = path.resolve(__dirname, 'uploads')

app.post('/upload', function (req, res) {

    const form = new multiparty.Form()
    form.parse(req, async (err, fields, files) => {
        if (err) {
            res.status(401).json({
                ok: false,
                msg: '上传失败，请重新上传'
            })
            return
        }

        const fileHash = fields['fileHash'][0]
        const chunkHash = fields['chunkHash'][0]

        //创建临时存放目录fileHash命名
        const chunkPath = path.resolve(UPLOAD_DIR, fileHash)
        if (!fse.existsSync(chunkPath)) {
            await fse.mkdir(chunkPath)
        }
        //将切片放入文件夹里面chunkHash命名
        const oldPath = files['chunk'][0]['path']//系统临时存放目录文件

        await fse.move(oldPath, path.resolve(chunkPath, chunkHash))

        res.status(200).json({
            ok: true,
            msg: '上传成功'
        })
    })
})

app.post('/merge', async function (req, res) {
    const { fileHash, filName, size } = req.body
    // console.log(fileHash, filName, size)

    //如果已经存在该文件，就没必要合并了
    //完整的文件的路径
    const filePath = path.resolve(UPLOAD_DIR, fileHash + extractExt(filName))

    //如果已经存在该文件，就没必要合并了
    if (fse.existsSync(filePath)) {
        res.status(200).json({
            ok: true,
            msg: '合并成功'
        })
        return
    }

    //如果不存在该文件，采取合并
    const chunkDir = path.resolve(UPLOAD_DIR, fileHash)
    if (!fse.existsSync(chunkDir)) {
        res.status(401).json({
            ok: false,
            msg: '合并失败，请重新上传'
        })
        return
    }

    //合并操作
    const chunkPaths = await fse.readdir(chunkDir)
    // console.log(chunkPaths,chunkPaths.length)
    //进行排序操作
    chunkPaths.sort((a, b) => {
        return a.split('-')[1] - b.split('-')[1]
    })
    console.log(chunkPaths)
    const list = chunkPaths.map((chunkName, index) => {
        return new Promise(resolve => {
            const chunkPath = path.resolve(chunkDir, chunkName)
            const readStream = fse.createReadStream(chunkPath)
            const writeStream = fse.createWriteStream(filePath, {
                start: index * size,
                end: (index + 1) * size
            })
            //读取完成后移出切片
            readStream.on('end', async () => {
                await fse.unlink(chunkPath)
                resolve()
            })
            readStream.pipe(writeStream)
        })
    })

    await Promise.all(list)
    await fse.remove(chunkDir)//删除创建的临时文件夹

    res.status(200).json({
        ok: true,
        msg: '合并成功'
    })
})

app.post('/verify', async function (req, res) {
    const { fileHash, filName } = req.body
    // console.log(fileHash, filName);

    const filePath = path.resolve(UPLOAD_DIR, fileHash + extractExt(filName))

    //返回服务器已经上传成功的切片
    const chunkDir=path.join(UPLOAD_DIR,fileHash)
    let chunkPaths=[]
    //如果存在对应的临时文件夹才去读取
    if(fse.existsSync(chunkDir)){
        chunkPaths = await fse.readdir(chunkDir)
        console.log(chunkPaths)
    }

    if (fse.existsSync(filePath)) {
        //如果存在就不用上传
        res.status(200).json({
            ok: true,
            shouldUpload: false
        })
    } else {
        //如果不存在重新上传
        res.status(200).json({
            ok: true,
            shouldUpload: true,
            existChunks:chunkPaths
        })
    }

})

app.listen(3000, () => {
    console.log('Server is running on port 3000')
})